#pragma once

#include <QObject>
#include <QNetworkReply>

class QNetworkAccessManager;
namespace AliOSS
{
	class AliOSSAdapter;

	/*!
	* @brief Uploader for AliOSS
	* AliOSSUploader has similar signals as QNetworkReply for users to \
	* retrive the status of uploading.
	*
	* usage :
	* @code
	* AliOSSAdapter adapter(...);
	* AliOSSUploader *uploader = adapter->prepareUpload(data);
	* uploader->setNeededInformation(path, signature);
	* uploader->upload();
	* @endcode
	*
	**/
	class AliOSSUploadRequest : public QObject
	{
		Q_OBJECT
	private:
		AliOSSUploadRequest(
			AliOSSAdapter *parent, 
			QNetworkAccessManager *networkAccessManager,
			const QString &bucket,
			const QString &accessId);
	public:
		void doUpload();
		void setNeededInformation(
			const QString &datetimestr,
			const QString &path,
			const QString &signature,
			const QString &contentType = QStringLiteral("application/octet-stream"),
			const QMap<QString, QByteArray> ossHeaders = QMap<QString, QByteArray>());
		QString remoteUrl();
	public:
		// getter
		QString datetimeString() { return dtstr; }
		QByteArray fileMd5inBase64() { return _fileMd5inBase64; }
	public:
		Q_SIGNAL void uploadFinished();
		Q_SIGNAL void uploadFailed();
		Q_SIGNAL void uploadError(QNetworkReply::NetworkError code);
		Q_SIGNAL void uploadProgress(qint64 bytesSent, qint64 bytesTotal);
	protected:
		void onRequestFinished();
	private:
		void prepare(const QByteArray & data);
	private:
		bool isOk();
	private:
		friend class AliOSSAdapter;
		QNetworkAccessManager *networkAccessManager = nullptr;
		QString bucket;
		QString accessId;

		QString path;
		QString dtstr;
		QString signature;
		QByteArray data;
		QByteArray _fileMd5inBase64;
		QString contentType;
		QMap<QString, QByteArray> ossHeaders;
		QNetworkReply *reply = nullptr;
	};
}